#!/usr/bin/env python
#-*-coding=utf8-*-

import unittest
import os
from datetime import date
from database import DataBase

class Task:
	def __init__(self, pr_key, tdate, subject, text):
		# from separated fields
		# pr_key, subject and text are strings
		# tdate is datetime.date object
		self.pr_key = pr_key
		self.date = tdate
		self.subject = subject
		self.text = text
	
	@staticmethod
	def from_string(string):
		# from string: "PRKEY|DD MM YY|SUBJ|TEXT"
		fields  = string.split('|')
		pr_key  = int(fields[0])
		tdate   = date(*map(int, reversed(fields[1].split(' '))))
		subject = fields[2]
		text    = fields[3]
		return (pr_key, tdate, subject, text)
	
	def __str__(self):
		return '|'.join((str(self.pr_key), 
						self.date.strftime("%d %m %y"), 
						self.subject, 
						self.text))

class TaskDB:
	def __init__(self, db, filename):
		self.db = db
		self.filename = filename
	
	def get_tasks(self):
		all_tasks = [Task(*Task.from_string(record)) \
					for record in self.db.extract_all(self.filename)]
		return all_tasks
	
	def get_task(self, primary_key):
		this_task = Task(*Task.from_string(self.db.get(self.filename, primary_key)))
		return this_task
	
	def put_task(self, task):
		self.db.add(self.filename, str(task))
	
	def del_task(self, pr_key):
		self.db.delete(self.filename, pr_key)
	
	def get_tasks_from_to(self, day_from, day_to):
		result = filter(lambda task: task if (day_from <= task.date <= day_to) else None,
					self.get_tasks())
		return result
	
	def get_tasks_for_day(self, day=date.today()):
		result = filter(lambda task: task if (task.date == day) else None,
						self.get_tasks())
		return result
	
	def get_tasks_for_last_cal_week(self, day_on_week=date.today()):
		is_this_week = lambda task: task if task.date.isocalendar()[2:]==day_on_week.isocalendar()[2:] else None
		result = filter(is_this_week, self.get_tasks())
		return result

'''
class DBMock:
	def __init__(self, dir):
		self.dir = dir
	def add(self, file, task):
		path = os.path.join(self.dir, file)
		with open(path, 'a') as fin:
			fin.write(task+'\n')
	def delete(self, file, pk):
		path = os.path.join(self.dir, file)
		with open(path) as fin:
			text = fin.readlines()
			for i,record in enumerate(text):
				if Task(*Task.from_string(record)).pr_key == pk:
					text[i] = text[-1]
					del text[-1]
					break
	def get(self, file, pk):
		path = os.path.join(self.dir, file)
		with open(path) as fin:
			text = fin.readlines()
			for i,record in enumerate(text):
				if Task(*Task.from_string(record)).pr_key == pk:
					result = record
					break
		return result
	def extract_all(self, file):
		path = os.path.join(self.dir, file)
		with open(path) as fin:
			text = fin.readlines()
		return text
'''
class DBMock:
	def __init__(self, dir):
		self.db_example = ['1|01 02 2011|Физика|Учебник И.И.Иванов стр.3 упр.5',
							'2|29 10 2011|Физика|Учебник И.И.Иванов стр.10 упр.6',
							'3|01 11 2011|Физика|Задачник И.И.Петров с/р 12',
							'4|03 11 2011|Русский|Написать диктант',
							'5|30 10 2011|Русский|Учебник С.С.Петров параграф 14 - читать',
							'6|15 09 2011|Математика|Подготовиться к к/р',
							'7|16 09 2010|Математика|x^2+6x+sqrt(3x-1)=5; x=?']
	def add(self, file, task):
		pass
	def delete(self, file, pk):
		pass
	def get(self, file, pk):
		for record in self.db_example:
			if Task(*Task.from_string(record)).pr_key == pk:
				return record
	def extract_all(self, file):
		return self.db_example
				
class TDB_Test(unittest.TestCase):
	def setUp(self):
		self.tdb = TaskDB(DBMock('.'), 'database.txt')
	
	def test_gettask(self):
		self.assertIsInstance(self.tdb.get_task(2), Task)
	
	def test_puttask(self):
		self.tdb.put_task(Task(10, date(2011,5,6), 'Литература', 'стихотворение наизусть'))
	
	def test_gettasksforday(self):
		res = self.tdb.get_tasks_for_day()
		self.assertIsInstance(res, list)
		if len(res) > 0:
			self.assertIsInstance(res[0], Task)
	
	def test_gettasksfromto(self):
		day_from = date(1,1,10)
		day_to = date.today()
		res = self.tdb.get_tasks_from_to(day_from, day_to)
		self.assertIsInstance(res, list)
		if len(res) > 0:
			self.assertIsInstance(res[0], Task)
	
	def test_lastcalweek(self):
		res = self.tdb.get_tasks_for_last_cal_week()
		self.assertIsInstance(res, list)
		if len(res) > 0:
			self.assertIsInstance(res[0], Task)

if __name__=="__main__":
	unittest.main()

